package com.googlecode.bip.dao;

import java.io.IOException;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import com.googlecode.bip.entity.IGenericUser;
import com.googlecode.bip.entity.IUser;
import com.googlecode.bip.entity.IllegalIdLocalException;
import com.googlecode.bip.entity.Role;

/**
 * DAO for {@link IUser}
 */
public interface UserDAO extends Serializable
{
    /**
     * Find an {@link IUser} in database using iduser
     *
     * @param iduser iduser to find
     * @return a new {@link IUser} if user is found, null otherwise
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public IUser findUser( final int iduser )
        throws NamingException, SQLException;

    /**
     * Find an {@link IGenericUser} in database using iduser
     *
     * @param iduser iduser to find
     * @return a new {@link IGenericUser} if user is found, null otherwise
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public IGenericUser findGenericUser( int iduser )
        throws NamingException, SQLException;

    /**
     * Find an {@link IUser} in database using username store on {@link HttpServletRequest}
     *
     * @param request  HttpServletRequest
     * @return a new IUser if user is found, null otherwise
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public IUser findUser( HttpServletRequest request )
        throws NamingException, SQLException;

    /**
     * Find an {@link IGenericUser} in database using username store on {@link HttpServletRequest}
     *
     * @param request  HttpServletRequest
     * @return a new IUser if user is found, null otherwise
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public IGenericUser findGenericUser( HttpServletRequest request )
        throws NamingException, SQLException;

    /**
     * Find an {@link IGenericUser} in database using 'username'
     * and 'password'
     *
     * @param username  user name
     * @param password  user password
     * @return a new IUser if user is found, null otherwise
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public IGenericUser findGenericUser( String username, String password )
        throws NamingException, SQLException;

    /**
     * Insert a new {@link IUser} in database (must not exist)
     *
     * @param username  user name to create
     * @param password  password for user name
     * @return a new {@link IUser} if user has been created, null if not.
     * @throws SQLException if any
     * @throws NamingException if any
     */
    public IUser insertUser( String username, String password )
        throws NamingException, SQLException;

    /**
     * Insert a new {@link IGenericUser} in database (must not exist).
     * <p>
     * If role equals to {@link Role#BIP_USER}, this method call {@link #insertUser(String, String)}
     * </p>
     *
     * @param username  user name to create
     * @param password  password for user name
     * @param role      {@link Role} for this new user.
     * @return a new {@link IUser} if user has been created, null if not.
     * @throws SQLException if any
     * @throws NamingException if any
     */
    public IGenericUser insertGenericUser( String username, String password, Role role )
        throws NamingException, SQLException;

    /**
     * Delete an {@link IUser}
     *
     * @param iduser iduser to find
     * @return true if User has been deleted, false on failure
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public boolean deleteUser( int iduser )
        throws NamingException, SQLException;

    /**
     * Update an {@link IUser} in database
     * <p>Note: Did not update fields: username, password, isactive</p>
     *
     * @param user {@link IUser} to update
     * @return true on success, false on failure or error
     * @throws NamingException if any
     * @throws SQLException if any
     * @throws IllegalIdLocalException if idlocal is not valid
     * @see #updateGenericUser(IGenericUser)
     */
    public boolean updateUser( IUser iuser )
        throws NamingException, SQLException, IllegalIdLocalException;

    /**
     * Update an {@link IGenericUser} in database.
     *
     * @param iGenericUser {@link IGenericUser} to update
     * @return true on success, false on failure or error
     * @throws NamingException if any
     * @throws SQLException if any
     */
    public boolean updateGenericUser( IGenericUser iGenericUser )
        throws NamingException, SQLException;

    /**
     * Change password of an {@link IGenericUser}
     *
     * @param iduser        {@link IGenericUser}  to update
     * @param oldPassword   Old password
     * @param newPassword   New password
     * @return true if password has been change.
     * @throws NamingException if any
     * @throws SQLException if any
     */
    boolean changeGenericUserPassword( int iduser, String oldPassword, String newPassword )
        throws NamingException, SQLException;

    /**
     * Store JSON configuration
     *
     * @param iGenericUser {@link IGenericUser} to update configuration
     * @param config JSON configuration String (could be null)
     * @return true if configuration has been store.
     * @throws NamingException if any
     * @throws SQLException if any
     * @throws UnsupportedEncodingException if any
     */
    public boolean updateGenericUserConfig(
            IGenericUser    iGenericUser,
            String          config
            )
        throws NamingException, SQLException, UnsupportedEncodingException;

    /**
     * Load JSON configuration
     *
     * @param iGenericUser {@link IGenericUser} to get configuration
     * @return JSON configuration String (could be null)
     * @throws SQLException if any
     * @throws NamingException if any
     * @throws IOException if any
     */
    public String getGenericUserConfig( IGenericUser iGenericUser )
        throws SQLException, NamingException, IOException;
}

